package com.gome.ocean.dao.websql;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLSyntaxErrorException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.alibaba.cobar.parser.ast.fragment.tableref.TableReference;
import com.alibaba.cobar.parser.ast.fragment.tableref.TableReferences;
import com.alibaba.cobar.parser.ast.stmt.dml.DMLSelectStatement;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery;
import com.alibaba.fastjson.JSONObject;
import com.gome.ocean.common.constants.Constants;
import com.gome.ocean.common.constants.WebSqlContants;
import com.gome.ocean.common.enums.ColumnTypeEnum;
import com.gome.ocean.common.enums.DataBaseType;
import com.gome.ocean.common.utils.DBUtil;
import com.gome.ocean.common.utils.GddlParseHelper;
import com.gome.ocean.common.utils.TableStruct;
import com.gome.ocean.dao.model.datasource.CharsetRule;
import com.gome.ocean.dao.model.dsm.CommonDataBaseDetail;
import com.gome.ocean.dao.model.websql.DBEditTableBean;
import com.gome.ocean.dao.model.websql.DBEditTableColumnBean;
import com.gome.ocean.dao.model.websql.DBView;
import com.gome.ocean.dao.model.websql.DataBaseVO;
import com.gome.ocean.dao.model.websql.DisplayColumnsVO;
import com.gome.ocean.dao.model.websql.ExplainVO;
import com.gome.ocean.dao.model.websql.MetadataVO;
import com.gome.ocean.dao.model.websql.MysqlIndexJsonBean;
import com.gome.ocean.dao.model.websql.MysqlRefJsonBean;
import com.gome.ocean.dao.model.websql.PostChangeResultVO;
import com.gome.ocean.dao.model.websql.PostChangeVO;
import com.gome.ocean.dao.model.websql.SqlResultVO;
import com.gome.ocean.dao.model.websql.SqlTemplateVo;
import com.gome.ocean.dao.model.websql.TableVO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.taobao.tddl.atom.config.TAtomConfParser;
import com.taobao.tddl.atom.config.TAtomDsConfDO;
import com.taobao.tddl.atom.config.TAtomDsConfHandle;
import com.taobao.tddl.common.exception.NotSupportException;
import com.taobao.tddl.optimizer.core.ast.QueryTreeNode;
import com.taobao.tddl.optimizer.parse.cobar.visitor.MySqlExprVisitor;

@Service("WebSqlEngine")
public class WebSqlEngineJdbcTemPlateImpl implements WebSqlEngine {

    private static final Logger LOG = LoggerFactory.getLogger(WebSqlEngineJdbcTemPlateImpl.class);

    @Override
    public Object select(CommonDataBaseDetail commonDataBaseDetail, String dbName, String sql, Integer pageNum,
                         Integer pageSize) throws SQLSyntaxErrorException {
        if (pageNum == null) pageNum = Constants.DEFAULT_PAGE_NUM;
        if (pageSize == null) pageSize = 10;
        SqlResultVO sqlResultVO = new SqlResultVO();
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        SQLStatement sqlStatement = GddlParseHelper.parseStatement(sql, commonDataBaseDetail.getDataBaseType());
        // 查询语句执行
        if (sqlStatement instanceof SQLSelectStatement) {
            Page page = new Page(pageNum, pageSize);
            Connection conn = null;
            ResultSet resultSet = null;
            try {
                sqlResultVO.setSqlType("1");
                // 组装查询数据
                String searchSql = null;
                if (DataBaseType.DRDS == commonDataBaseDetail.getDataBaseType()) {
                    searchSql = buildMysqlPageSql(sql, page);
                    conn = commonDataBaseDetail.getDataSource().getConnection();// drds移除超时时间
                                                                                // 否则有可能获取不到连接
                } else if (DataBaseType.MySql == commonDataBaseDetail.getDataBaseType()) {
                    searchSql = buildMysqlPageSql(sql, page);
                    conn = commonDataBaseDetail.getDataSource().getConnection(1000);
                } else if (DataBaseType.Oracle == commonDataBaseDetail.getDataBaseType()) {
                    searchSql = buildOralcePageSql(sql, page);
                    conn = commonDataBaseDetail.getDataSource().getConnection(1000);
                }
                String tableName = null;
                SQLTableSource ts = null;
                SQLSelect sqlSelect = ((SQLSelectStatement) sqlStatement).getSelect();
                if(sqlSelect.getQuery() instanceof SQLUnionQuery){
                	SQLUnionQuery sqlSelectQuery = (SQLUnionQuery) sqlSelect.getQuery();
                	SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) sqlSelectQuery.getLeft();
                	ts = queryBlock.getFrom();
                }else{
                	SQLSelectQueryBlock  sqlSelectQuery = (SQLSelectQueryBlock) sqlSelect.getQuery();
                	ts = sqlSelectQuery.getFrom();
                }
                if (ts != null && ts.toString().contains(",") || StringUtils.contains(ts.toString(), "JOIN")) {
                    sqlResultVO.setCanEdit(false);
                    sqlResultVO.setCanNotEditReason("查询结果集中包含多个表,不能进行编辑。");
                } else {
                    if (DataBaseType.MySql == commonDataBaseDetail.getDataBaseType()
                        || DataBaseType.DRDS == commonDataBaseDetail.getDataBaseType()) {
                        tableName = getTableNode(ts.toString()).toLowerCase();
                    } else if (DataBaseType.Oracle == commonDataBaseDetail.getDataBaseType()) {
                        tableName = getTableNode(ts.toString());
                    }
                }
                Map<String, Object> disMataMaps = getDisplayMata(commonDataBaseDetail.getDataBaseType(),
                    conn,
                    resultSet,
                    dbName,
                    tableName,
                    searchSql);
                sqlResultVO.setDisplayColumns((List<DisplayColumnsVO>) disMataMaps.get("displayColumnsVOs"));
                sqlResultVO.setMetadata((List<MetadataVO>) disMataMaps.get("metadataVOs"));
                sqlResultVO.setData((List<Map<String, Object>>) disMataMaps.get("data"));
                List<String> primaryKeys = (List<String>) disMataMaps.get("primaryKeys");
                if (primaryKeys != null && primaryKeys.size() > 0) {
                    sqlResultVO.setCanEdit(true);
                    sqlResultVO.setEditDbName(dbName);
                    sqlResultVO.setEditTableName(tableName);
                } else {
                    sqlResultVO.setCanEdit(false);
                    sqlResultVO.setCanNotEditReason("查询结果集中没有主键,不能进行编辑。");
                }
                sqlResultVO.setEditTablePrimaryKeys(primaryKeys);
                sqlResultVO.setRows(sqlResultVO.getData().size());
                stopWatch.stop();
                sqlResultVO.setTimeDelay(stopWatch.getTime());
                sqlResultVO
                    .setMsg("执行成功，当前返回：[" + sqlResultVO.getRows() + "]行，耗时：[" + sqlResultVO.getTimeDelay() + "ms.]");
                return sqlResultVO;
            } catch (SQLException e) {
                LOG.error(e.toString());
                return e.getMessage();
            } finally {
                DBUtil.closeDBResources(resultSet, null, conn);
            }
        } else if (sqlStatement instanceof SQLInsertStatement) {
            if (DataBaseType.DRDS == commonDataBaseDetail.getDataBaseType()) {
                return "don't allow this operation! sql:" + sql;
            }
            Connection conn = null;
            try {
                conn = commonDataBaseDetail.getDataSource().getConnection(1000);
                sqlResultVO.setSqlType("9");
                sqlResultVO.setResultType("dml");
                sqlResultVO.setDisplayColumns(Collections.<DisplayColumnsVO> emptyList());
                sqlResultVO.setRows(DBUtil.update(conn, sql));
                stopWatch.stop();
                sqlResultVO.setTimeDelay(stopWatch.getTime());
                sqlResultVO
                    .setMsg("执行成功，当前返回：[" + sqlResultVO.getRows() + "]行，耗时：[" + sqlResultVO.getTimeDelay() + "ms.]");
                return sqlResultVO;
            } catch (SQLException e) {
                LOG.error(e.toString());
                return e.getMessage();
            } finally {
                DBUtil.closeDBResources(null, null, conn);
            }
        } else if (sqlStatement instanceof SQLUpdateStatement) {
            if (DataBaseType.DRDS == commonDataBaseDetail.getDataBaseType()) {
                return "don't allow this operation! sql:" + sql;
            }
            Connection conn = null;
            try {
                conn = commonDataBaseDetail.getDataSource().getConnection(1000);
                sqlResultVO.setSqlType("9");
                sqlResultVO.setResultType("dml");
                sqlResultVO.setDisplayColumns(Collections.<DisplayColumnsVO> emptyList());
                sqlResultVO.setRows(DBUtil.update(conn, sql));
                stopWatch.stop();
                sqlResultVO.setTimeDelay(stopWatch.getTime());
                sqlResultVO
                    .setMsg("执行成功，当前返回：[" + sqlResultVO.getRows() + "]行，耗时：[" + sqlResultVO.getTimeDelay() + "ms.]");
                return sqlResultVO;
            } catch (SQLException e) {
                LOG.error(e.toString());
                return e.getMessage();
            } finally {
                DBUtil.closeDBResources(null, null, conn);
            }
        } else if (sqlStatement instanceof SQLDeleteStatement) {
            if (DataBaseType.DRDS == commonDataBaseDetail.getDataBaseType()) {
                return "don't allow this operation! sql:" + sql;
            }
            Connection conn = null;
            try {
                conn = commonDataBaseDetail.getDataSource().getConnection(1000);
                sqlResultVO.setSqlType("9");
                sqlResultVO.setResultType("dml");
                sqlResultVO.setDisplayColumns(Collections.<DisplayColumnsVO> emptyList());
                sqlResultVO.setRows(DBUtil.update(conn, sql));
                stopWatch.stop();
                sqlResultVO.setTimeDelay(stopWatch.getTime());
                sqlResultVO
                    .setMsg("执行成功，当前返回：[" + sqlResultVO.getRows() + "]行，耗时：[" + sqlResultVO.getTimeDelay() + "ms.]");
                return sqlResultVO;
            } catch (SQLException e) {
                LOG.error(e.toString());
                return e.getMessage();
            } finally {
                DBUtil.closeDBResources(null, null, conn);
            }
        } else {
            Connection conn = null;
            try {
                conn = commonDataBaseDetail.getDataSource().getConnection(1000);
                // 组装查询数据
                String postSql = null;
                if (DataBaseType.MySql == commonDataBaseDetail.getDataBaseType()
                    || DataBaseType.DRDS == commonDataBaseDetail.getDataBaseType()) {
                    postSql = sql;
                } else if (DataBaseType.Oracle == commonDataBaseDetail.getDataBaseType()) {
                    postSql = StringUtils.replace(sql, "`", "");
                }
                sqlResultVO.setSqlType("9");
                sqlResultVO.setResultType("dml");
                sqlResultVO.setDisplayColumns(Collections.<DisplayColumnsVO> emptyList());
                sqlResultVO.setRows(DBUtil.update(conn, postSql));
                stopWatch.stop();
                sqlResultVO.setTimeDelay(stopWatch.getTime());
                sqlResultVO
                    .setMsg("执行成功，当前返回：[" + sqlResultVO.getRows() + "]行，耗时：[" + sqlResultVO.getTimeDelay() + "ms.]");
                return sqlResultVO;
            } catch (SQLException e) {
                LOG.error(e.toString());
                return e.getMessage();
            } finally {
                DBUtil.closeDBResources(null, null, conn);
            }
        }
    }

    @Override
    public Object execute(CommonDataBaseDetail dataBaseDetail, String dbName, String sql) {
        List<PostChangeVO> postChangeVOs = JSONObject.parseArray(sql, PostChangeVO.class);
        List<PostChangeResultVO> changeResultVOs = new ArrayList<PostChangeResultVO>();
        if (CollectionUtils.isNotEmpty(postChangeVOs)) {
            Connection conn = null;
            try {
                String postSql = null;
                conn = dataBaseDetail.getDataSource().getConnection(1000);
                for (PostChangeVO postChangeVO : postChangeVOs) {
                    if (DataBaseType.Oracle == dataBaseDetail.getDataBaseType()) {
                        postSql = StringUtils.replace(StringUtils.replace(postChangeVO.getSql(), "`", ""), ";", "");
                    } else {
                        postSql = postChangeVO.getSql();
                    }
                    switch (postChangeVO.getType()) {
                        case "D":
                            PostChangeResultVO deleteResult = new PostChangeResultVO();
                            deleteResult.setLastInsertId(DBUtil.update(conn, postSql));
                            deleteResult.setRowIndex(postChangeVO.getRowIndex());
                            changeResultVOs.add(deleteResult);
                            break;
                        case "I":
                            PostChangeResultVO insertResult = new PostChangeResultVO();
                            insertResult.setLastInsertId(DBUtil.update(conn, postSql));
                            insertResult.setRowIndex(postChangeVO.getRowIndex());
                            changeResultVOs.add(insertResult);
                            break;
                        case "U":
                            PostChangeResultVO updateResult = new PostChangeResultVO();
                            updateResult.setLastInsertId(DBUtil.update(conn, postSql));
                            updateResult.setRowIndex(postChangeVO.getRowIndex());
                            changeResultVOs.add(updateResult);
                            break;
                        default:
                            break;
                    }
                }
                return changeResultVOs;
            } catch (SQLException e) {
                LOG.error(ExceptionUtils.getMessage(e));
                return e.getMessage();
            } finally {
                DBUtil.closeDBResources(null, null, conn);
            }
        }
        return changeResultVOs;
    }

    public static class Page {

        private int pageNum;
        private int pageSize;
        private int startRow;
        private int endRow;

        public Page(int pageNum, int pageSize){
            this.pageNum = pageNum;
            this.pageSize = pageSize;
            this.startRow = pageNum > 0 ? (pageNum - 1) * pageSize : 0;
            this.endRow = pageNum * pageSize;
        }

        public int getEndRow() {
            return endRow;
        }

        public void setEndRow(int endRow) {
            this.endRow = endRow;
        }

        public int getPageNum() {
            return pageNum;
        }

        public void setPageNum(int pageNum) {
            this.pageNum = pageNum;
        }

        public int getPageSize() {
            return pageSize;
        }

        public void setPageSize(int pageSize) {
            this.pageSize = pageSize;
        }

        public int getStartRow() {
            return startRow;
        }

        public void setStartRow(int startRow) {
            this.startRow = startRow;
        }
    }

    private Map<String, Object> getDisplayMata(DataBaseType dataBaseType, Connection conn, ResultSet resultSet,
                                               String dbName, String tableName, String sql) throws SQLException {
        Map<String, Object> result = new HashMap<String, Object>();
        List<DisplayColumnsVO> displayColumnsVOs = new ArrayList<DisplayColumnsVO>();
        displayColumnsVOs.add(new DisplayColumnsVO(0, 38, false, true, true, "backgroud-color:red", "rownumberer"));
        List<MetadataVO> metadataVOs = new ArrayList<MetadataVO>();
        Map<String, Object> tableMaps = DBUtil.getColumnInfoMetaData(dataBaseType, conn, dbName, tableName, sql);
        int columnIndex = 1;
        Set<TableStruct> structSets = (Set<TableStruct>) tableMaps.get("structSets");
        for (TableStruct tableStruct : structSets) {
            DisplayColumnsVO displayColumnsVO = new DisplayColumnsVO();
            displayColumnsVO.setMinWidth(120);
            displayColumnsVO.setWidth(120);
            displayColumnsVO.setReadOnly(false);
            displayColumnsVO.setResizable(true);
            displayColumnsVO.setSortable(true);
            displayColumnsVO.setDataIndex("COLUMN_" + columnIndex);
            displayColumnsVO.setText(tableStruct.getColumnName());
            displayColumnsVOs.add(displayColumnsVO);

            MetadataVO metadataVO = new MetadataVO();
            metadataVO.setAutoIncrement(tableStruct.getIsAutoIncrement());
            metadataVO.setDataType(tableStruct.getColumnType());
            metadataVO.setDbName(dbName);
            metadataVO.setTableName(tableStruct.getTableName());
            metadataVO.setLabel(tableStruct.getColumnName());
            metadataVO.setRealName(tableStruct.getColumnName());
            metadataVO.setName("COLUMN_" + columnIndex);
            metadataVO.setSize(StringUtils.isNotEmpty(tableStruct.getColumnSize()) ? Integer
                .parseInt(tableStruct.getColumnSize()) : null);
            metadataVOs.add(metadataVO);
            columnIndex++;
        }
        result.put("displayColumnsVOs", displayColumnsVOs);
        result.put("metadataVOs", metadataVOs);
        result.put("data", tableMaps.get("data"));
        result.put("primaryKeys", tableMaps.get("primaryKeys"));
        return result;
    }

    private String getTableNode(String table) {
        return StringUtils.substringAfter(table, ".");
    }

    private QueryTreeNode getTableNode(DMLSelectStatement node) {
        TableReferences trs = node.getTables();
        List<TableReference> tbls = trs.getTableReferenceList();
        QueryTreeNode table = null;
        if (tbls != null && tbls.size() == 1) {
            MySqlExprVisitor tv = new MySqlExprVisitor();
            tbls.get(0).accept(tv);
            table = tv.getTableNode();
        } else {
            throw new NotSupportException("not support more than one table update!");
        }
        return table;
    }

    private String buildOralcePageSql(String sql, Page page) {
        StringBuilder pageSql = new StringBuilder();
        pageSql.append("select * from ( select temp.*, rownum row_id from ( ");
        pageSql.append(sql);
        pageSql.append(" ) temp where rownum <= ").append(page.getEndRow());
        pageSql.append(") where row_id > ").append(page.getStartRow());
        return pageSql.toString();
    }

    /**
     * 添加limit语句，<br>
     * 先要确保原sql语句不包含limit语句
     * 
     * @param sql
     * @param pageNum
     * @param pageSize
     * @return
     */
    private String buildMysqlPageSql(String sql, Page page) {
        StringBuilder pageSql = new StringBuilder();
        pageSql.append(sql);
        pageSql.append(" limit ");
        pageSql.append(page.getStartRow()).append(",");
        pageSql.append(page.getPageSize());
        return pageSql.toString();
    }

    /**
     * 组装标准的查询语句
     */
    private String standardQuerySql(CommonDataBaseDetail dataBaseDetail, String dbName, String tableName) {
        String sql = "SELECT * FROM " + dbName + "." + tableName;
        // 组装查询数据
        String searchSql = null;
        Page page = new Page(1, 10);
        if (DataBaseType.MySql == dataBaseDetail.getDataBaseType()
            || DataBaseType.DRDS == dataBaseDetail.getDataBaseType()) {
            searchSql = buildMysqlPageSql(sql, page);
        } else if (DataBaseType.Oracle == dataBaseDetail.getDataBaseType()) {
            searchSql = buildOralcePageSql(sql, page);
        }
        return searchSql;
    }

    @Override
    public Object select(CommonDataBaseDetail commonDataBaseDetail, String dbName,
                         String sql) throws SQLSyntaxErrorException {
        return select(commonDataBaseDetail, dbName, sql, 0, 0);
    }

    @Override
    public List<DataBaseVO> getDataBase(CommonDataBaseDetail dataBaseDetail) throws SQLException {
        List<String> dataBaseList = DBUtil.getDataBaseByConn(dataBaseDetail.getDataBaseType(),
            dataBaseDetail.getDataSource().getConnection(1000),
            dataBaseDetail.getDbName());
        List<DataBaseVO> dataBaseVOs = new ArrayList<DataBaseVO>();
        if (CollectionUtils.isNotEmpty(dataBaseList)) {
            for (String database : dataBaseList) {
                DataBaseVO dataBaseVO = new DataBaseVO();
                dataBaseVO.setData(database);
                dataBaseVO.setLabel(database);
                dataBaseVOs.add(dataBaseVO);
            }
            return dataBaseVOs;
        }
        return dataBaseVOs;
    }

    @Override
    public List<TableVO> getTable(CommonDataBaseDetail dataBaseDetail, String dbName,
                                  String[] types) throws SQLException {
        List<String> tables = DBUtil.getTablesByConn(dataBaseDetail.getDataBaseType(),
            dataBaseDetail.getDataSource().getConnection(1000),
            dbName,
            dataBaseDetail.getUser(),
            types);
        String type = types[0];
        List<TableVO> tableVOs = new ArrayList<TableVO>();
        if (CollectionUtils.isNotEmpty(tables)) {
            for (String table : tables) {
                TableVO tableVO = new TableVO();
                if (type.equalsIgnoreCase("VIEW")) {
                    tableVO.setIconCls("mysql_viewIcon");
                    tableVO.setLeaf(true);
                } else {
                    tableVO.setIconCls("mysql_tableIcon");
                }
                tableVO.setId(table);
                tableVO.setRealText(table);
                tableVO.setTreeType("table");
                tableVO.setType("SYSTEM VIEW");
                tableVO.setText(table);
                tableVOs.add(tableVO);
            }
            return tableVOs;
        }
        return tableVOs;
    }

    @Override
    public List<TableVO> getLikeTable(CommonDataBaseDetail dataBaseDetail, String dbName, String likeTableName,
                                      String[] types) throws SQLException {
        List<String> tables = DBUtil.getTablesByConn(dataBaseDetail.getDataBaseType(),
            dataBaseDetail.getDataSource().getConnection(1000),
            dbName,
            dataBaseDetail.getUser(),
            types);
        List<TableVO> tableVOs = new ArrayList<TableVO>();
        if (CollectionUtils.isNotEmpty(tables)) {
            for (String table : tables) {
                if (StringUtils.contains(table, likeTableName)) {
                    TableVO tableVO = new TableVO();
                    tableVO.setIconCls("mysql_tableIcon");
                    tableVO.setId(table);
                    tableVO.setRealText(table);
                    tableVO.setTreeType("table");
                    tableVO.setType("SYSTEM VIEW");
                    tableVO.setText(table);
                    tableVOs.add(tableVO);
                }
            }
            return tableVOs;
        }
        return tableVOs;
    }

    @Override
    public List<TableVO> getTableColumnAndIndex(CommonDataBaseDetail dataBaseDetail, String dbName,
                                                String tableName) throws SQLException {
        List<TableVO> tableVOs = new ArrayList<TableVO>();
        String searchSql = this.standardQuerySql(dataBaseDetail, dbName, tableName);
        Integer[] columnAndPk = DBUtil.getColumnAndIndexCount(dataBaseDetail.getDataBaseType(),
            dataBaseDetail.getDataSource().getConnection(1000),
            dbName,
            tableName,
            searchSql);
        TableVO columnVO = new TableVO();
        columnVO.setTreeType("column_group");
        columnVO.setTableName(tableName);
        columnVO.setRealName("column_group");
        columnVO.setType("column_group");
        columnVO.setRealText("&#21015;");
        columnVO.setId(tableName + "$$columns");
        columnVO.setIconCls("mysql_columnIcon");
        columnVO.setText("&#21015;&#65288;" + columnAndPk[1] + "&#65289;");
        tableVOs.add(columnVO);

        TableVO indexVO = new TableVO();
        indexVO.setTreeType("index_group");
        indexVO.setId(tableName + "$$indexs");
        indexVO.setRealText("&#32034;&#24341;");
        indexVO.setTableName(tableName);
        indexVO.setRealName("index_group");
        indexVO.setType("index_group");
        indexVO.setIconCls("mysql_indexIcon");
        indexVO.setText("&#32034;&#24341;&#65288;" + columnAndPk[0] + "&#65289;");
        tableVOs.add(indexVO);
        return tableVOs;
    }

    @Override
    public List<TableVO> getTableColumnDetail(CommonDataBaseDetail dataBaseDetail, String dbName,
                                              String tableName) throws SQLException {
        String searchSql = this.standardQuerySql(dataBaseDetail, dbName, tableName);
        List<Map<String, String>> columnMaps = DBUtil.getColumnDetail(dataBaseDetail.getDataBaseType(),
            dataBaseDetail.getDataSource().getConnection(1000),
            dbName,
            tableName,
            searchSql);
        List<TableVO> tableVOs = new ArrayList<TableVO>();
        for (Map<String, String> columnMap : columnMaps) {
            TableVO columnVO = new TableVO();
            columnVO.setTreeType("column");
            columnVO.setLeaf(true);
            columnVO.setTableName(tableName);
            columnVO.setRealName(columnMap.get("columnName"));
            columnVO.setType("column");
            columnVO.setRealText("<b>" + columnMap.get("columnName") + "</b>&nbsp;" + columnMap.get("columnType") + "");
            columnVO.setId("" + tableName + "$$" + columnMap.get("columnName") + "$$column");
            columnVO.setIconCls("mysql_columnIcon");
            columnVO.setText("<b>" + columnMap.get("columnName") + "</b>&nbsp;" + columnMap.get("columnType") + "");
            tableVOs.add(columnVO);
        }
        return tableVOs;
    }

    @Override
    public List<TableVO> getTableIndexDetail(CommonDataBaseDetail dataBaseDetail, String dbName,
                                             String tableName) throws SQLException {
        List<Map<String, Object>> columnMaps = DBUtil.getTableIndexDetailInfo(dataBaseDetail.getDataBaseType(),
            dataBaseDetail.getDataSource().getConnection(1000),
            dbName,
            tableName);
        List<TableVO> tableVOs = new ArrayList<TableVO>();
        if (columnMaps != null && columnMaps.size() > 0) {
            for (Map<String, Object> columnMap : columnMaps) {
                TableVO columnVO = new TableVO();
                columnVO.setTreeType("index");
                columnVO.setType("index");
                columnVO.setLeaf(true);
                columnVO.setTableName(tableName);
                columnVO.setRealName(columnMap.get("name").toString());
                columnVO.setRealText(
                    "<b>" + columnMap.get("name").toString() + "</b>（" + columnMap.get("columns").toString() + "）");
                columnVO.setId("" + tableName + "$$" + columnMap.get("name").toString() + "_"
                               + columnMap.get("columns").toString() + "$$index");
                if (DataBaseType.Oracle == dataBaseDetail.getDataBaseType()) {
                    String indexType = columnMap.get("type").toString();
                    if (indexType.equals("UNIQUE")) {
                        columnVO.setIconCls("mysql_pkeyIcon");
                    } else {
                        columnVO.setIconCls("mysql_indexIcon");
                    }
                } else {
                    if (columnMap.get("name").toString().equals("PRIMARY")) {
                        columnVO.setIconCls("mysql_pkeyIcon");
                    } else {
                        columnVO.setIconCls("mysql_indexIcon");
                    }
                }
                columnVO.setText(
                    "<b>" + columnMap.get("name").toString() + "</b>（" + columnMap.get("columns").toString() + "）");
                tableVOs.add(columnVO);
            }
        }
        return tableVOs;
    }

    @Override
    public Map<String, Object> getAutoCompleteTableColumns(CommonDataBaseDetail dataBaseDetail, String dbName,
                                                           String[] types) throws SQLException {
        Map<String, Object> tableColumnsMaps = new HashMap<String, Object>();
        List<String> dataBaseList = DBUtil.getDataBaseByConn(dataBaseDetail.getDataBaseType(),
            dataBaseDetail.getDataSource().getConnection(1000),
            dataBaseDetail.getDbName());
        tableColumnsMaps.put("databases", dataBaseList);

        List<String> tables = DBUtil.getTablesByConn(dataBaseDetail.getDataBaseType(),
            dataBaseDetail.getDataSource().getConnection(1000),
            dbName,
            dataBaseDetail.getUser(),
            types);
        tableColumnsMaps.put("tables", tables);
        return tableColumnsMaps;
    }

    @Override
    public Map<String, Object> getDataBaseInfo(CommonDataBaseDetail dataBaseDetail) throws SQLException {
        return DBUtil.getDataBaseInfo(dataBaseDetail.getDataBaseType(),
            dataBaseDetail.getDataSource().getConnection(1000));
    }

    @Override
    public List<String> splitSQL(String sqlText) throws SQLException {
        List<String> sqlList = new ArrayList<String>();
        String[] splits = StringUtils.split(sqlText, ";");
        for (int i = 0; i < splits.length; i++) {
            sqlList.add(splits[i]);
        }
        return sqlList;
    }

    @Override
    public Object getSqlPlan(CommonDataBaseDetail dataBaseDetail, String dbName, String sql) throws SQLException {
        List<ExplainVO> explainVOs = new ArrayList<ExplainVO>();
        List<Map<String, String>> columnMaps = DBUtil.getSqlPlain(dataBaseDetail.getDataBaseType(),
            dataBaseDetail.getDataSource().getConnection(1000),
            dbName,
            sql);
        if (!columnMaps.isEmpty()) {
            for (Map<String, String> coMap : columnMaps) {
                ExplainVO explainVO = new ExplainVO();
                explainVO.setSelect_type(coMap.get("SELECT_TYPE"));
                explainVO.setRows(Integer.valueOf(coMap.get("ROWS")));
                explainVO.setExtra(coMap.get("EXTRA"));
                explainVO.setId(Integer.valueOf(coMap.get("ID")));
                explainVO.setTable(coMap.get("TABLE"));
                explainVO.setPossible_keys(coMap.get("POSSIBLE_KEYS"));
                explainVO.setType(coMap.get("TYPE"));
                explainVO.setKey_len(coMap.get("KEY_LEN") != null ? Integer.valueOf(coMap.get("KEY_LEN")) : 0);
                explainVO.setKey(coMap.get("KEY"));
                explainVO.setRef(coMap.get("REF"));
                explainVOs.add(explainVO);
            }
        }
        return explainVOs;
    }

    @Override
    public Map<String, Object> showTableAllColumns(CommonDataBaseDetail dataBaseDetail, String dbName,
                                                   String tableName) throws SQLException {
        Map<String, Object> map = Maps.newHashMap();
        if (StringUtils.isNotEmpty(dbName) && StringUtils.isNotEmpty(tableName)) {
            String searchSql = this.standardQuerySql(dataBaseDetail, dbName, tableName);
            List<Map<String, String>> columnMaps = DBUtil.getColumnDetail(dataBaseDetail.getDataBaseType(),
                dataBaseDetail.getDataSource().getConnection(1000),
                dbName,
                tableName,
                searchSql);
            List<CharsetRule> dataList = Lists.newArrayList();
            for (Map<String, String> columnMap : columnMaps) {
                CharsetRule rule = new CharsetRule();
                rule.setData(columnMap.get("columnName"));
                rule.setLabel(columnMap.get("columnName"));
                dataList.add(rule);
            }
            if (dataList != null && dataList.size() > 0) {
                map.put("root", dataList);
                map.put("success", true);
                map.put("failure", false);
                return map;
            }
        }
        map.put("root", "Table '" + dbName + "." + tableName + "' doesn't exist");
        map.put("success", false);
        map.put("failure", true);
        return map;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Map<String, Object> getTableStructer(CommonDataBaseDetail dataBaseDetail, String dbName, String tableName,
                                                boolean isShowCreate, boolean isShowIndex, boolean isShowRef,
                                                boolean isShowDrop, boolean isShowTruncate) throws SQLException {
        Map<String, Object> map = Maps.newHashMap();
        try {
            StringBuilder createStrB = new StringBuilder();
            StringBuffer priKeyBuff = new StringBuffer();
            StringBuffer indexBuff = new StringBuffer();
            StringBuffer refBuff = new StringBuffer();
            DBEditTableBean editTableBean = new DBEditTableBean();
            List<DBEditTableColumnBean> dbTableColumnLists = Lists.newArrayList();
            List<MysqlIndexJsonBean> indexBeanLists = Lists.newArrayList();
            List<MysqlRefJsonBean> refBeanLists = Lists.newArrayList();
            if (isShowCreate) {
                if (StringUtils.isNotEmpty(dbName) && StringUtils.isNotBlank(tableName)) {
                    String searchSql = this.standardQuerySql(dataBaseDetail, dbName, tableName);
                    Map<String, Object> columnMaps = DBUtil.getColumnInfoMetaData(dataBaseDetail.getDataBaseType(),
                        dataBaseDetail.getDataSource().getConnection(1000),
                        dbName,
                        tableName,
                        searchSql);
                    // 构建列信息
                    if (columnMaps != null && columnMaps.size() > 0) {
                        Set<TableStruct> tableStruct = (Set<TableStruct>) columnMaps.get("structSets");
                        if (tableStruct != null && tableStruct.size() > 0) {
                            // 是否构建Drop语句
                            if (isShowDrop) {
                                if (dataBaseDetail.getDataBaseType() == DataBaseType.Oracle) {
                                    createStrB.append("BEGIN")
                                        .append("\r\n")
                                        .append("\t")
                                        .append("EXECUTE IMMEDIATE '")
                                        .append("DROP TABLE ")
                                        .append(tableName)
                                        .append("';")
                                        .append("\r\n")
                                        .append("\t")
                                        .append("EXCEPTION WHEN OTHERS THEN NULL;\r\n")
                                        .append("END;")
                                        .append("\r\n");
                                } else {
                                    createStrB.append("DROP TABLE IF EXISTS ")
                                        .append(tableName)
                                        .append(";")
                                        .append("\r\n");
                                }
                            }
                            createStrB.append("CREATE TABLE ").append(tableName).append("(").append("\r\n");
                            priKeyBuff.append(" PRIMARY KEY (");
                            for (TableStruct table : tableStruct) {
                                DBEditTableColumnBean columnBean = new DBEditTableColumnBean();
                                columnBean.setAutoIncrement(table.getIsAutoIncrement());
                                columnBean.setColumnName(table.getColumnName());
                                if (table.getColumnType().contains("BIGINT")) {
                                    columnBean.setColumnType("bigint");
                                } else if (table.getColumnType().contains("INT UNSIGNED")) {
                                    columnBean.setColumnType("int");
                                } else {
                                    columnBean.setColumnType(table.getColumnType().toLowerCase());
                                }
                                columnBean.setLength(table.getColumnSize());
                                columnBean.setOldColumnName(table.getColumnName());
                                columnBean.setColumnDisplayType(
                                    columnBean.getColumnType().toLowerCase() + "(" + table.getColumnSize() + ")");
                                List<String> priKeyLists = (List<String>) columnMaps.get("primaryKeys");
                                if (priKeyLists != null && priKeyLists.size() > 0) {
                                    for (String pri : priKeyLists) {
                                        if (pri.equals(columnBean.getColumnName())) {
                                            columnBean.setPrimaryKey(true);
                                            priKeyBuff.append("`")
                                                .append(columnBean.getColumnName())
                                                .append("`")
                                                .append(",");
                                        }
                                    }
                                }
                                columnBean = this.translateColumnType(columnBean, columnBean.getColumnType());
                                columnBean.setComments(table.getColumnComment());
                                dbTableColumnLists.add(columnBean);
                                createStrB.append(columnBean.getColumnName())
                                    .append(" ")
                                    .append(columnBean.getColumnDisplayType())
                                    .append(" ");
                                if (table.isNull()) {
                                    createStrB.append(" DEFAULT NULL ");
                                } else {
                                    createStrB.append(" NOT NULL ");
                                }
                                if (table.getIsAutoIncrement()) {
                                    createStrB.append(" AUTO_INCREMENT ");
                                }
                                if (StringUtils.isNotBlank(columnBean.getComments())) {
                                    createStrB.append(" COMMENT '").append(columnBean.getComments()).append("'");
                                }
                                createStrB.append(",").append("\r\n");
                            }
                            priKeyBuff.deleteCharAt(priKeyBuff.length() - 1).append(")");
                            if (priKeyBuff.indexOf("`") > 1) {
                                createStrB.append(priKeyBuff.toString().replaceAll("`", "")).append(",");
                            }
                        }
                    }
                }
            }
            // 构建索引信息
            if (isShowIndex) {
                List<Map<String, Object>> indexMapLists = DBUtil.getTableIndexDetailInfo(
                    dataBaseDetail.getDataBaseType(),
                    dataBaseDetail.getDataSource().getConnection(1000),
                    dbName,
                    tableName);
                if (indexMapLists != null && indexMapLists.size() > 0) {
                    for (Map<String, Object> indexMap : indexMapLists) {
                        MysqlIndexJsonBean index = new MysqlIndexJsonBean();
                        if (StringUtils.isBlank(indexMap.get("columns").toString())) continue;
                        index.setName(indexMap.get("name").toString());
                        index.setOldIndexName(indexMap.get("oldIndexName").toString());
                        index.setColumns(indexMap.get("columns").toString());
                        index.setMethod(indexMap.get("method").toString());
                        index.setType(indexMap.get("type").toString());
                        indexBeanLists.add(index);
                        if (dataBaseDetail.getDataBaseType() == DataBaseType.Oracle) {
                            StringBuffer commStr = new StringBuffer();
                            if (StringUtils.isNotBlank(index.getColumns())) {
                                String column = "";
                                if (index.getColumns().contains("(")) {
                                    column = index.getColumns().substring(0, index.getColumns().indexOf("("));
                                } else {
                                    column = index.getColumns();
                                }
                                commStr.append(index.getName())
                                    .append(" ON ")
                                    .append(dbName)
                                    .append(".")
                                    .append(tableName)
                                    .append("(")
                                    .append(column)
                                    .append(" ")
                                    .append(index.getMethod())
                                    .append(")");
                            }
                            if (StringUtils.isNotBlank(index.getType())) {
                                if (index.getType().equals("INDEX")) {
                                    indexBuff.append("CREATE INDEX ").append(dbName).append(".").append(commStr);
                                } else if (index.getType().equals("UNIQUE")) {
                                    indexBuff.append("CREATE UNIQUE INDEX ").append(dbName).append(".").append(commStr);
                                } else if (index.getType().equals("BITMAP")) {
                                    indexBuff.append("CREATE BITMAP INDEX ").append(dbName).append(".").append(commStr);
                                }
                            }
                            if (StringUtils.isNotBlank(index.getColumns())) {
                                indexBuff.append(";").append("\r\n");
                            }
                        } else {
                            if (StringUtils.isNotBlank(index.getType())) {
                                StringBuffer commStr = new StringBuffer();
                                commStr.append("`")
                                    .append(index.getName())
                                    .append("`(`")
                                    .append(index.getColumns())
                                    .append("`)");
                                if (index.getType().equals("NORMAL")) {
                                    indexBuff.append(" KEY ").append(commStr);
                                } else if (index.getType().equals("UNIQUE")) {
                                    indexBuff.append(" UNIQUE KEY ").append(commStr);
                                } else if (index.getType().equals("FULLTEXT")) {
                                    indexBuff.append(" FULLTEXT KEY ").append(commStr);
                                }
                            }

                            if (StringUtils.isNotBlank(index.getMethod())) {
                                indexBuff.append(" USING ").append(index.getMethod());
                            }
                            if (StringUtils.isNotBlank(index.getColumns())) {
                                indexBuff.append(",").append("\r\n");
                            }
                        }
                    }
                    if (!(dataBaseDetail.getDataBaseType() == DataBaseType.Oracle)) {
                        createStrB.append(indexBuff);
                    }
                }
            }

            // 构建外键信息
            if (isShowRef) {
                List<Map<String, Object>> refMapLists = DBUtil.getTableReferenceDetailInfo(
                    dataBaseDetail.getDataBaseType(),
                    dataBaseDetail.getDataSource().getConnection(1000),
                    dbName,
                    tableName);
                if (refMapLists != null && refMapLists.size() > 0) {
                    for (Map<String, Object> refMap : refMapLists) {
                        MysqlRefJsonBean ref = new MysqlRefJsonBean();
                        ref.setColumns(refMap.get("columns").toString());
                        ref.setName(refMap.get("name").toString());
                        ref.setOldRefName(refMap.get("oldRefName").toString());
                        ref.setRefDBName(refMap.get("refDBName").toString());
                        ref.setRefTableName(refMap.get("refTableName").toString());
                        ref.setRefColumns(refMap.get("refColumns").toString());
                        ref.setUpdateAction(refMap.get("updateAction").toString());
                        ref.setDeleteAction(refMap.get("deleteAction").toString());
                        refBeanLists.add(ref);
                        if (dataBaseDetail.getDataBaseType() == DataBaseType.Oracle) {
                            if (StringUtils.isNotBlank(ref.getName())) {
                                refBuff.append(" CONSTRAINT ").append(ref.getName()).append(" FOREIGN KEY (");
                            }
                            if (StringUtils.isNotBlank(ref.getColumns())) {
                                StringBuffer includeColumn = new StringBuffer();
                                StringBuffer refColumn = new StringBuffer();
                                String[] includeColArr = ref.getColumns().split(",");
                                for (String i : includeColArr) {
                                    includeColumn.append(i).append(",");
                                }
                                if (StringUtils.isNotBlank(ref.getRefDBName())
                                    || StringUtils.isNotBlank(ref.getRefTableName())
                                    || StringUtils.isNotBlank(ref.getRefColumns())) {
                                    refBuff.append(includeColumn.deleteCharAt(includeColumn.length() - 1))
                                        .append(") REFERENCES ")
                                        .append(ref.getRefDBName())
                                        .append(".")
                                        .append(ref.getRefTableName())
                                        .append(" (");
                                    String[] refColArr = ref.getRefColumns().split(",");
                                    for (String r : refColArr) {
                                        refColumn.append(r).append(",");
                                    }
                                    refBuff.append(refColumn.deleteCharAt(refColumn.length() - 1)).append(")");
                                }
                                refBuff.append(",").append("\r\n");
                            }
                        } else {
                            if (StringUtils.isNotBlank(ref.getName())) {
                                refBuff.append(" CONSTRAINT `").append(ref.getName()).append("` FOREIGN KEY (");
                            }
                            if (StringUtils.isNotBlank(ref.getColumns())) {
                                StringBuffer includeColumn = new StringBuffer();
                                StringBuffer refColumn = new StringBuffer();
                                String[] includeColArr = ref.getColumns().split(",");
                                for (String i : includeColArr) {
                                    includeColumn.append("`").append(i).append("`,");
                                }
                                if (StringUtils.isNotBlank(ref.getRefDBName())
                                    || StringUtils.isNotBlank(ref.getRefTableName())
                                    || StringUtils.isNotBlank(ref.getRefColumns())) {
                                    refBuff.append(includeColumn.deleteCharAt(includeColumn.length() - 1))
                                        .append(") REFERENCES `")
                                        .append(ref.getRefDBName())
                                        .append("`.`")
                                        .append(ref.getRefTableName())
                                        .append("` (");
                                    String[] refColArr = ref.getRefColumns().split(",");
                                    for (String r : refColArr) {
                                        refColumn.append("`").append(r).append("`,");
                                    }
                                    refBuff.append(refColumn.deleteCharAt(refColumn.length() - 1))
                                        .append(") ON DELETE ")
                                        .append(ref.getDeleteAction())
                                        .append(" ON UPDATE ")
                                        .append(ref.getUpdateAction());
                                }
                                refBuff.append(",").append("\r\n");
                            }
                        }
                    }
                    createStrB.append(refBuff);
                }
            }

            createStrB.deleteCharAt(createStrB.lastIndexOf(",")).append(")").append(editTableBean.getCreateOption());
            // 是否显示truncate 语句
            StringBuffer trunStr = new StringBuffer();
            if (isShowTruncate) {
                trunStr.append("\r\n truncate table ").append(tableName).append(";\r\n");
            }
            // 构建建表信息
            String createScript = "";
            if (dataBaseDetail.getDataBaseType() == DataBaseType.Oracle) {
                createScript = createStrB.append(";").append("\r\n").append(trunStr).append(indexBuff).toString();
            } else {
                createScript = createStrB.append(";").append(trunStr).toString();
            }

            // 构建总行数
            String countSql = "SELECT COUNT(*) FROM " + dbName + "." + tableName;
            Map<String, Object> countMap = DBUtil.querySQLCounts(dataBaseDetail.getDataSource().getConnection(1000),
                countSql,
                dataBaseDetail.getDataBaseType());
            if (countMap != null && countMap.size() > 0) {
                editTableBean.setRows(Integer.parseInt(countMap.get("counts").toString()));
            }

            // 构建基本信息
            editTableBean.setColumns(dbTableColumnLists);
            editTableBean.setIndexes(indexBeanLists);
            editTableBean.setReferences(refBeanLists);
            editTableBean.setDbName(dbName);
            editTableBean.setTableName(tableName);
            editTableBean.setCreateScript(createScript);
            map.put("root", editTableBean);
            map.put("success", true);
            map.put("failure", false);
        } catch (Exception e) {
            map.put("root", "获取表结构错误,异常信息:" + ExceptionUtils.getMessage(e));
            map.put("failure", true);
            map.put("success", false);
            LOG.error(ExceptionUtils.getMessage(e));
        }

        return map;
    }

    // 数据类型
    private DBEditTableColumnBean translateColumnType(DBEditTableColumnBean bean, String columnType) throws Exception {
        try {
            columnSwitch: switch (ColumnTypeEnum.getColumnType(columnType)) {
                case INT:
                case BIGINT:
                    bean.setIntField(true);
                    break columnSwitch;
                case NUMBER:
                    bean.setNumberField(true);
                    break columnSwitch;
                case CHAR:
                case VARCHAR:
                case VARCHAR2:
                    bean.setCharField(true);
                    break columnSwitch;
                case BLOB:
                case LONGBLOB:
                    bean.setBlobFiled(true);
                    break columnSwitch;
                case TEXT:
                case LONGTEXT:
                    bean.setTextField(true);
                    break columnSwitch;
                case DATE:
                    bean.setDateField(true);
                    break columnSwitch;
                case DATETIME:
                    bean.setDatetime(true);
                    break columnSwitch;
                case TIMESTAMP:
                    bean.setTimestamp(true);
                    break columnSwitch;
                case FLOAT:
                    bean.setFloatField(true);
                    break columnSwitch;
                default:
                    bean.setOtherField(true);
            }
        } catch (Exception e) {
            throw new RuntimeException(
                "该表中当前列[" + bean.getColumnName() + "]的数据类型[" + columnType + "]为不符合规范的数据类型,请联系管理员!" + e);
        }
        return bean;
    }

    @SuppressWarnings("resource")
    @Override
    public Map<String, Object> vaildateDatasourceByTddlInfo(String globaConfStr, String appConfStr,
                                                            String dbPwd) throws SQLException {
        Map<String, Object> map = Maps.newHashMap();
        DruidDataSource druidDataSource = new DruidDataSource();
        try {
            TAtomDsConfDO runTimeConf = TAtomConfParser.parserTAtomDsConfDO(globaConfStr, appConfStr);
            druidDataSource = TAtomDsConfHandle.convertTAtomDsConf2DruidConf("valid",
                runTimeConf,
                runTimeConf.getDbName());
            druidDataSource.setInitialSize(1);
            druidDataSource.setPassword(dbPwd);

            druidDataSource.init();
            map.put("success", true);
            map.put("failure", false);
            map.put("root", "验证成功,符合配置规则");
        } catch (Exception e) {
            LOG.error(ExceptionUtils.getMessage(e));
            map.put("success", false);
            map.put("failure", true);
            map.put("info", ExceptionUtils.getMessage(e));
        } finally {
            druidDataSource.close();
        }
        return map;
    }

    @Override
    public Map<String, Object> getViewContent(CommonDataBaseDetail dataBaseDetail, String dbName,
                                              String viewName) throws SQLException {
        Map<String, Object> map = Maps.newHashMap();
        try {
            Map<String, Object> resultMap = DBUtil.getDataBaseDetailViewInfo(dataBaseDetail.getDataBaseType(),
                dataBaseDetail.getDataSource().getConnection(1000),
                dbName,
                viewName);
            DBView view = new DBView();
            if (resultMap != null && resultMap.size() > 0) {
                if (dataBaseDetail.getDataBaseType() == DataBaseType.Oracle) {
                    if (resultMap.get("content") != null) {
                        view.setContent(resultMap.get("content").toString());
                    }
                } else {
                    if (resultMap.get("content") != null
                        && StringUtils.isNoneBlank(resultMap.get("content").toString())) {
                        view.setContent(resultMap.get("content").toString());
                    }
                    if (resultMap.get("definer") != null
                        && StringUtils.isNoneBlank(resultMap.get("definer").toString())) {
                        view.setDefiner(resultMap.get("definer").toString());
                    }
                    if (resultMap.get("sqlSecurity") != null
                        && StringUtils.isNoneBlank(resultMap.get("sqlSecurity").toString())) {
                        view.setSqlSecurity(resultMap.get("sqlSecurity").toString());
                    }
                    if (resultMap.get("checkOption") != null
                        && StringUtils.isNoneBlank(resultMap.get("checkOption").toString())) {
                        view.setCheckOption(resultMap.get("checkOption").toString());
                    }
                }
            }
            view.setName(viewName);

            map.put("root", view);
            map.put("success", true);
            map.put("failure", false);
        } catch (Exception e) {
            map.put("success", false);
            map.put("failure", true);
            map.put("root", ExceptionUtils.getMessage(e));
        }
        return map;
    }

    @Override
    public Map<String, Object> getOneColumnDetailInfo(CommonDataBaseDetail dataBaseDetail, String dbName,
                                                      String tableName, String columnName) throws SQLException {
        Map<String, Object> map = Maps.newHashMap();
        DBEditTableColumnBean columnBean = new DBEditTableColumnBean();
        try {
            if (StringUtils.isNotEmpty(dbName) && StringUtils.isNotBlank(tableName)
                && StringUtils.isNotBlank(columnName)) {
                String searchSql = this.standardQuerySql(dataBaseDetail, dbName, tableName);
                Map<String, Object> columnMaps = DBUtil.getColumnInfoMetaData(dataBaseDetail.getDataBaseType(),
                    dataBaseDetail.getDataSource().getConnection(1000),
                    dbName,
                    tableName,
                    searchSql);
                // 构建列信息
                if (columnMaps != null && columnMaps.size() > 0) {
                    Set<TableStruct> tableStruct = (Set<TableStruct>) columnMaps.get("structSets");
                    if (tableStruct != null && tableStruct.size() > 0) {
                        for (TableStruct table : tableStruct) {
                            if (table.getColumnName().equalsIgnoreCase(columnName)) {
                                columnBean.setAutoIncrement(table.getIsAutoIncrement());
                                columnBean.setColumnName(table.getColumnName());
                                if (table.getColumnType().contains("BIGINT")) {
                                    columnBean.setColumnType("bigint");
                                } else if (table.getColumnType().contains("INT UNSIGNED")) {
                                    columnBean.setColumnType("int");
                                } else {
                                    columnBean.setColumnType(table.getColumnType().toLowerCase());
                                }
                                columnBean.setLength(table.getColumnSize());
                                columnBean.setOldColumnName(table.getColumnName());
                                columnBean.setColumnDisplayType(
                                    columnBean.getColumnType().toLowerCase() + "(" + table.getColumnSize() + ")");
                                List<String> priKeyLists = (List<String>) columnMaps.get("primaryKeys");
                                if (priKeyLists != null && priKeyLists.size() > 0) {
                                    for (String pri : priKeyLists) {
                                        if (pri.equals(columnBean.getColumnName())) {
                                            columnBean.setPrimaryKey(true);
                                        }
                                    }
                                }
                                columnBean = this.translateColumnType(columnBean, columnBean.getColumnType());
                                columnBean.setComments(table.getColumnComment());
                            }
                        }
                    }
                }
            }
            map.put("root", columnBean);
            map.put("success", true);
            map.put("failure", false);
        } catch (Exception e) {
            map.put("success", false);
            map.put("failure", true);
            map.put("root", ExceptionUtils.getMessage(e));
        }
        return map;
    }

    @Override
    public Map<String, Object> getOneIndexDetailInfo(CommonDataBaseDetail dataBaseDetail, String dbName,
                                                     String tableName, String indexName) throws SQLException {
        Map<String, Object> map = Maps.newHashMap();
        MysqlIndexJsonBean index = new MysqlIndexJsonBean();
        try {
            List<Map<String, Object>> indexMapLists = DBUtil.getTableIndexDetailInfo(dataBaseDetail.getDataBaseType(),
                dataBaseDetail.getDataSource().getConnection(1000),
                dbName,
                tableName);
            if (indexMapLists != null && indexMapLists.size() > 0) {
                for (Map<String, Object> indexMap : indexMapLists) {
                    if (indexMap.get("name").toString().equals(indexName)) {
                        if (StringUtils.isBlank(indexMap.get("columns").toString())) continue;
                        index.setName(indexMap.get("name").toString());
                        index.setOldIndexName(indexMap.get("oldIndexName").toString());
                        index.setColumns(indexMap.get("columns").toString());
                        index.setMethod(indexMap.get("method").toString());
                        index.setType(indexMap.get("type").toString());
                    }
                }
            }
            map.put("root", index);
            map.put("success", true);
            map.put("failure", false);
        } catch (Exception e) {
            map.put("success", false);
            map.put("failure", true);
            map.put("root", ExceptionUtils.getMessage(e));
        }
        return map;
    }

    @Override
    public SqlTemplateVo getAllProcedureFunTrigEventInfo(CommonDataBaseDetail dataBaseDetail, String dbName,
                                                         boolean isProcedurce, boolean isFun, boolean isTrigger,
                                                         boolean isEvent) throws SQLException {
        SqlTemplateVo templateVo = new SqlTemplateVo();
        templateVo.setId("gmwebsql_" + dataBaseDetail.getDataBaseType().getTypeFullName() + "_program_root");
        templateVo.setText("gmwebsql_" + dataBaseDetail.getDataBaseType().getTypeFullName() + "_program_root");
        templateVo.setLeaf(false);
        templateVo.setExpanded(false);
        List<SqlTemplateVo> temLists = Lists.newLinkedList();
        try {
            // 获取存储过程信息
            if (isProcedurce) {
                SqlTemplateVo proceTem = new SqlTemplateVo();
                proceTem.setId("存储过程");
                proceTem.setText("存储过程");
                proceTem.setLeaf(false);
                proceTem.setExpanded(true);
                proceTem.setIconCls("mysql_prodIcon");
                List<Map<String, Object>> proceBeanLists = DBUtil.getTableProcedureFuncDetailData(
                    dataBaseDetail.getDataBaseType(),
                    dataBaseDetail.getDataSource().getConnection(1000),
                    dbName,
                    null,
                    WebSqlContants.WEBSQL_PROCEDURE);
                if (proceBeanLists != null && proceBeanLists.size() > 0) {
                    List<SqlTemplateVo> proceLists = Lists.newArrayList();
                    for (Map<String, Object> proceMap : proceBeanLists) {
                        SqlTemplateVo proceBean = new SqlTemplateVo();
                        proceBean.setId("proce_" + proceMap.get("name"));
                        proceBean.setRealText(proceMap.get("name").toString());
                        proceBean.setText(proceMap.get("name").toString());
                        proceBean.setLeaf(true);
                        proceBean.setExpanded(false);
                        proceBean.setIconCls("mysql_prodIcon");
                        proceLists.add(proceBean);
                    }
                    proceTem.setChildren(proceLists);
                }
                temLists.add(proceTem);
            }
            // 获取函数信息
            if (isFun) {
                SqlTemplateVo funcTem = new SqlTemplateVo();
                funcTem.setId("函数");
                funcTem.setText("函数");
                funcTem.setLeaf(false);
                funcTem.setExpanded(true);
                funcTem.setIconCls("mysql_funIcon");
                List<Map<String, Object>> funcBeanLists = DBUtil.getTableProcedureFuncDetailData(
                    dataBaseDetail.getDataBaseType(),
                    dataBaseDetail.getDataSource().getConnection(1000),
                    dbName,
                    null,
                    WebSqlContants.WEBSQL_FUNCTION);
                if (funcBeanLists != null && funcBeanLists.size() > 0) {
                    List<SqlTemplateVo> funcLists = Lists.newArrayList();
                    for (Map<String, Object> funcMap : funcBeanLists) {
                        SqlTemplateVo funcBean = new SqlTemplateVo();
                        funcBean.setId("func_" + funcMap.get("name"));
                        funcBean.setRealText(funcMap.get("name").toString());
                        funcBean.setText(funcMap.get("name").toString());
                        funcBean.setLeaf(true);
                        funcBean.setExpanded(false);
                        funcBean.setIconCls("mysql_funIcon");
                        funcLists.add(funcBean);
                    }
                    funcTem.setChildren(funcLists);
                }
                temLists.add(funcTem);
            }
            // 获取触发器信息
            if (isTrigger) {
                SqlTemplateVo triggerTem = new SqlTemplateVo();
                triggerTem.setId("触发器");
                triggerTem.setText("触发器");
                triggerTem.setLeaf(false);
                triggerTem.setExpanded(true);
                triggerTem.setIconCls("mysql_triIcon");
                List<Map<String, Object>> triggerBeanLists = DBUtil.getTableProcedureFuncDetailData(
                    dataBaseDetail.getDataBaseType(),
                    dataBaseDetail.getDataSource().getConnection(1000),
                    dbName,
                    null,
                    WebSqlContants.WEBSQL_TRIGGER);
                if (triggerBeanLists != null && triggerBeanLists.size() > 0) {
                    List<SqlTemplateVo> triggerLists = Lists.newArrayList();
                    for (Map<String, Object> triggerMap : triggerBeanLists) {
                        SqlTemplateVo triggerBean = new SqlTemplateVo();
                        triggerBean.setId("trig_" + triggerMap.get("name"));
                        triggerBean.setRealText(triggerMap.get("name").toString());
                        triggerBean.setText(triggerMap.get("name").toString());
                        triggerBean.setLeaf(true);
                        triggerBean.setExpanded(false);
                        triggerBean.setIconCls("mysql_triIcon");
                        triggerLists.add(triggerBean);
                    }
                    triggerTem.setChildren(triggerLists);
                }
                temLists.add(triggerTem);
            }
            // 获取事件信息
            if (!isEvent) {
                SqlTemplateVo eventTem = new SqlTemplateVo();
                eventTem.setId("事件");
                eventTem.setText("事件");
                eventTem.setLeaf(false);
                eventTem.setExpanded(true);
                eventTem.setIconCls("mysql_eventIcon");
                List<Map<String, Object>> eventBeanLists = DBUtil.getTableProcedureFuncDetailData(
                    dataBaseDetail.getDataBaseType(),
                    dataBaseDetail.getDataSource().getConnection(1000),
                    dbName,
                    null,
                    WebSqlContants.WEBSQL_EVENT);
                if (eventBeanLists != null && eventBeanLists.size() > 0) {
                    List<SqlTemplateVo> eventLists = Lists.newArrayList();
                    for (Map<String, Object> eventMap : eventBeanLists) {
                        SqlTemplateVo eventBean = new SqlTemplateVo();
                        eventBean.setId("event_" + eventMap.get("name"));
                        eventBean.setRealText(eventMap.get("name").toString());
                        eventBean.setText(eventMap.get("name").toString());
                        eventBean.setLeaf(true);
                        eventBean.setExpanded(false);
                        eventBean.setIconCls("mysql_eventIcon");
                        eventLists.add(eventBean);
                    }
                    eventTem.setChildren(eventLists);
                }
                temLists.add(eventTem);
            }
            templateVo.setChildren(temLists);
        } catch (Exception e) {
            LOG.error("获取getAllProcedureFunTrigEventInfo 方法：异常信息:" + ExceptionUtils.getMessage(e));
        }
        return templateVo;
    }

    @Override
    public Map<String, Object> getProcedureFuncTrigEventDetailInfo(CommonDataBaseDetail dataBaseDetail, String dbName,
                                                                   String objName, String objType) throws SQLException {
        Map<String, Object> map = Maps.newHashMap();
        try {
            List<Map<String, Object>> contentLists = DBUtil.getTableProcedureFuncDetailData(
                dataBaseDetail.getDataBaseType(),
                dataBaseDetail.getDataSource().getConnection(1000),
                dbName,
                objName,
                objType);
            if (contentLists != null && contentLists.size() > 0) {
                map = contentLists.get(0);
            }
        } catch (Exception e) {
            LOG.error(ExceptionUtils.getMessage(e));
            map.put("success", false);
            map.put("failure", true);
            map.put("root", ExceptionUtils.getMessage(e));
        }
        return map;
    }

}
